package com.ttscm.srds.utils;

import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import com.ttscm.srds.datagram.SeerDataPacket;
import org.tinylog.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;

/**
 * @version:
 * @author:
 * @className:
 * @packageName:
 * @description:
 * @date: 2022/07/21
 */
public final class ConnectionUtil {

    public static SeerDataPacket connectSeerRobot(String host, int port, byte[] reqPackets) throws IOException {
        Logger.info("开始连接seer机器人：-IP: " + host + " -PORT: " + port);
        try (Socket socket = new Socket(host, port);
             OutputStream os = socket.getOutputStream();
             InputStream is = socket.getInputStream()) {

            Logger.info("成功连接seer机器人：-" + socket.getRemoteSocketAddress());
            Logger.info("上位系统请求报文：" + PacketUtil2.printPacketsHex(reqPackets));

            os.write(reqPackets);
            os.flush();
            socket.shutdownOutput();

            byte[] resPackets = new byte[1024 * 1024];
            byte[] tmpPackets = new byte[1];
            int i = 0;
            while ((is.read(tmpPackets)) != -1) {
                System.arraycopy(tmpPackets, 0, resPackets, i++, 1);
            }
            SeerDataPacket dataPacket = PacketUtil2.unmarshalSeerPacket(resPackets);
            Logger.info("seer机器人响应：" + dataPacket.toString());

            return dataPacket;
        }
    }

    public static void writeModbusRegisters(String host, int port, int slaveId, int startAddress, int[] registers) throws UnknownHostException, ModbusIOException, ModbusProtocolException, ModbusNumberException {
        Logger.info("开始连接线边设备：-IP: " + host + " -PORT: " + port);
        TcpParameters parameters = new TcpParameters();
        InetAddress adress = InetAddress.getByName(host);
        parameters.setHost(adress);
        parameters.setPort(port);
        parameters.setKeepAlive(true);
        ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(parameters);
        Modbus.setAutoIncrementTransactionId(true);
        try {
            if (!master.isConnected()) {
                master.connect();
            }
            master.writeMultipleRegisters(slaveId, startAddress, registers);
        } finally {
            master.disconnect();
        }
        StringBuilder sb = new StringBuilder();
        for (int value : registers) {
            sb.append(value).append(" ");
        }
        Logger.info("成功写入线边设备：-IP: " + host + " -PORT: " + port + "值：" + sb);
    }

    public static int[] readModbusHoldingRegisters(String host, int port, int slaveId, int startAddress, int quantity) throws UnknownHostException, ModbusIOException, ModbusProtocolException, ModbusNumberException {
        Logger.info("开始连接线边设备：-IP: " + host + " -PORT: " + port);
        TcpParameters parameters = new TcpParameters();
        InetAddress adress = InetAddress.getByName(host);
        parameters.setHost(adress);
        parameters.setPort(port);
        parameters.setKeepAlive(true);
        ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(parameters);
        Modbus.setAutoIncrementTransactionId(true);
        int[] registers;
        try {
            if (!master.isConnected()) {
                master.connect();
            }
            registers = master.readHoldingRegisters(slaveId, startAddress, quantity);
        } finally {
            master.disconnect();
        }
        StringBuilder sb = new StringBuilder();
        for (int value : registers) {
            sb.append(value).append(" ");
        }
        Logger.info("成功读取线边设备：-IP: " + host + " -PORT: " + port + "值：" + sb);

        return registers;
    }

    public static int readSiemensPlcS7(String host, int port, String address) {
        Logger.info("开始连接线边设备：-IP: " + host + " -PORT: " + port);

        S7PLC s7plc = new S7PLC(EPlcType.S1200, host, port, 0, 0);
        int signal = s7plc.readUInt16(address);
        s7plc.close();

        Logger.info("成功读取线边设备：-IP: " + host + " -PORT: " + port + "值：" + signal);

        return signal;
    }

    public static void writeSiemensPlcS7(String host, int port, String address, int signal) {
        Logger.info("开始连接线边设备：-IP: " + host + " -PORT: " + port);

        S7PLC s7plc = new S7PLC(EPlcType.S1200, host, port, 0, 0);
        s7plc.writeUInt16(address, signal);
        s7plc.close();

        Logger.info("成功写入线边设备：-IP: " + host + " -PORT: " + port + "值：" + signal);
    }


    public static String genSeerTaskId() {
        return "TTSCM" + System.currentTimeMillis() + "R" + String.format("%03d", new Random().nextInt(1000));
    }
}
